package edu.gatech.volt2.drdoommgt.presenter;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.swing.JOptionPane;

import edu.gatech.volt2.drdoommgt.domain.Doctor;
import edu.gatech.volt2.drdoommgt.domain.Labwork;
import edu.gatech.volt2.drdoommgt.domain.Login;
import edu.gatech.volt2.drdoommgt.domain.Nurse;
import edu.gatech.volt2.drdoommgt.domain.Patient;
import edu.gatech.volt2.drdoommgt.domain.SysAdmin;
import edu.gatech.volt2.drdoommgt.domain.User;
import edu.gatech.volt2.drdoommgt.domain.UserType;
import edu.gatech.volt2.drdoommgt.exceptions.LoginException;
import edu.gatech.volt2.drdoommgt.gui.ILoginView;
import edu.gatech.volt2.drdoommgt.gui.LoginWindow;
import edu.gatech.volt2.drdoommgt.system.DataBaseAccessor;

public class LoginPresenter implements ActionListener{
	private static DataBaseAccessor dba;
	private Login log;
	private ILoginView myView;
	private UserType type;
	private Map<String, Integer> attempts;
	private int MAX_ATTEMPTS = 3;
	

	public LoginPresenter() {
		attempts = new HashMap<String, Integer>();

		this.myView= new LoginWindow();
		myView.addListener(this);
		myView.showSelf();
		dba= new DataBaseAccessor();
		dba.connectToDatabase();
	}

	public LoginPresenter(ILoginView view){
		attempts = new HashMap<String, Integer>();

		this.myView= view;
		myView.addListener(this);
		myView.showSelf();
		dba= new DataBaseAccessor();
		dba.connectToDatabase();
	}

	public void actionPerformed(ActionEvent action) {
		if ( action.getSource() == myView.getCancelButton()){
			System.out.println("Exiting.");
			myView.closeSelf();
			dba.closeConnectionToDatabase();
		}
		else if(action.getSource() == myView.getSubmitButton()){
			String email = myView.getEmail();
			myView.setErrorMessage("");
			if ( myView.getEmail().length() == 0 ){
				myView.setErrorMessage("Enter your Email");
				return;
			}else if( myView.getPassword().length() == 0){
				myView.setErrorMessage("Enter your password");
				return;
			}
			try {
				Map<UserType, User> foundUser = Login.loginProcess(dba, email, myView.getPassword());
				
				Object[] keys = foundUser.keySet().toArray();
				UserType foundType = (UserType) keys[0];
				
				if(foundType == UserType.DOCTOR){
						DoctorPresenter pre = new DoctorPresenter((Doctor)foundUser.get(UserType.DOCTOR), dba);
				}else if(foundType == UserType.NURSE){
					NursePresenter pre = new NursePresenter((Nurse)foundUser.get(UserType.NURSE), dba);
				}else if(foundType == UserType.PATIENT){
					PatientPresenter pre = new PatientPresenter((Patient)foundUser.get(UserType.PATIENT), dba);
				}else if(foundType == UserType.SYSTEM_ADMIN){
					SysAdminPresenter pre = new SysAdminPresenter((SysAdmin)foundUser.get(UserType.SYSTEM_ADMIN), dba);
				}
				myView.hideSelf();
			} catch (LoginException e) {
				if ( e.getMessage() == "No User Found"){
					myView.setErrorMessage("No such user!");
				}
				else if ( e.getMessage() == "User suspended" ){
					myView.setErrorMessage("User Suspended!");
					JOptionPane.showMessageDialog(null, "This user is suspended and cannot log in!");
				}else if ( e.getMessage() == "Incorrect Password" ){
					myView.setErrorMessage("Incorrent! You have : "+(MAX_ATTEMPTS-this.getAttempts(email))+" tries left");
					if (this.getAttempts(email) >= MAX_ATTEMPTS){
						User u = dba.findByEmail(email);
						u.setSuspended(true);
						dba.save(u);
						JOptionPane.showMessageDialog(null, "Your user has been suspended. Too many login attempts.");
					}
					this.addAttempt(email);
				}
			}
		}
	}

	/**
	 * @param attempts the attempts to set
	 */
	public void addAttempt(String email) {
		if (attempts.containsKey(email)){
			if ( attempts.get(email) == MAX_ATTEMPTS ){
				return;
			}
			attempts.put(email, attempts.get(email)+1);
		}else{
			attempts.put(email, 1);
		}
	}

	/**
	 * @return the attempts
	 */
	public Integer getAttempts(String email) {
		if ( attempts.containsKey(email)){
			return attempts.get(email);
		}else{
			return 0;
		}
	}
	

}
